package xyz.xtt.pay.service.order;

import static xyz.xtt.common.asset.AssertUtils.isFalse;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Objects;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.xtt.asset.api.enums.GoodsTypeEnum;
import xyz.xtt.equity.api.dto.GetOnSaleBenefitPackageRequest;
import xyz.xtt.equity.api.dto.TblBenefitPackageDto;
import xyz.xtt.exchange.client.ExchangeClient;
import xyz.xtt.pay.api.enums.PayOrderBusinessTypeEnum;
import xyz.xtt.pay.api.enums.PayOrderStatusEnum;
import xyz.xtt.pay.client.request.MakeOrderRequest;
import xyz.xtt.pay.constants.ErrorMessage;
import xyz.xtt.pay.constants.PayConstants;
import xyz.xtt.pay.entity.TblBusinessOrder;
import xyz.xtt.pay.exception.ChainException;
import xyz.xtt.pay.service.BusinessOrderOperator;
import xyz.xtt.pay.service.IInnerService;
import xyz.xtt.pay.service.INftOrderService;
import xyz.xtt.pay.service.ITblBusinessOrderService;

/**
 * 权益包业务订单操作
 *
 * @author dale
 * @date 2025/3/14
 **/
@Service
@Slf4j
public class BenefitBusinessOrderOperator implements BusinessOrderOperator {
	@Autowired
	private ExchangeClient exchangeClient;
	@Autowired
	private ITblBusinessOrderService iTblBusinessOrderService;
	@Autowired
	private INftOrderService nftOrderService;
	@Autowired
	private IInnerService iInnerService;

	/**
	 * 是否支持该类型的订单
	 *
	 * @param type
	 * @return
	 */
	@Override
	public boolean canOperateType(PayOrderBusinessTypeEnum type) {
		return Objects.equals(PayOrderBusinessTypeEnum.NFT_VIP_MONTH, type) || Objects.equals(PayOrderBusinessTypeEnum.NFT_VIP_SEASON, type)
				|| Objects.equals(PayOrderBusinessTypeEnum.NFT_VIP_YEAR, type);
	}

	/**
	 * 创建订单
	 *
	 * @param uid              用户ID
	 * @param makeOrderRequest 创建订单请求
	 * @return 订单
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public TblBusinessOrder makeOrder(String uid, MakeOrderRequest makeOrderRequest) {
		LocalDateTime now = LocalDateTime.now();
		long buyerId = Long.parseLong(uid);
		String orderType = makeOrderRequest.getOrderType();
		TblBenefitPackageDto onSalePackage = getOnSaleBenefitPackage(orderType);
		GoodsTypeEnum goodsTypeEnum = GoodsTypeEnum.valueOf(orderType);
		String goodsId = String.valueOf(onSalePackage.getPackageId());

		// 检查是否有待支付的订单
		TblBusinessOrder unPayOrder = iTblBusinessOrderService.getUnPayBusinessOrder(buyerId, goodsTypeEnum.getCode(), goodsId);
		if (unPayOrder != null) {
			return unPayOrder;
		}

		TblBusinessOrder order = new TblBusinessOrder();
		order.setOrderId(IdUtil.getSnowflakeNextId());
		order.setGoodsId(goodsId);
		order.setGoodsType(goodsTypeEnum.getCode());
		order.setGoodsName(onSalePackage.getPackageName());
		order.setGoodsImage(onSalePackage.getImageUrl());
		order.setSellerId(PayConstants.TONGTONG_PLATFROM_USER_ID);
		order.setAppUserId(buyerId);
		order.setPurchaseNum(makeOrderRequest.getPurchaseAmount());
		BigDecimal totalPrice = onSalePackage.getSalePrice().setScale(2, RoundingMode.HALF_UP);
		// 测试用户重置价格
		totalPrice = nftOrderService.testUserResetPrice(buyerId, totalPrice);
		order.setOriginPrice(totalPrice);
		order.setRealPrice(order.getOriginPrice());
		order.setTransportPrice(BigDecimal.ZERO);
		order.setDiscountAmount(BigDecimal.ZERO);
		order.setTotalPrice(calculateOrderTotalPrice(order));
		order.setPayAmount(order.getTotalPrice());
		order.setOrderStatus(PayOrderStatusEnum.UN_PAY.getCode());
		order.setOrderTime(now);
		order.setCreateTime(now);
		order.setUpdateTime(now);
		isFalse(iTblBusinessOrderService
				.save(order), ErrorMessage.ORDER_CREATE_FAILED, () -> log.error("save order failed. order:{}", JSONUtil.toJsonStr(order)));
		return order;
	}

	private TblBenefitPackageDto getOnSaleBenefitPackage(String packageCode) {
		GetOnSaleBenefitPackageRequest onSaleBenefitPackageRequest = new GetOnSaleBenefitPackageRequest();
		onSaleBenefitPackageRequest.setPackageCode(packageCode);
		TblBenefitPackageDto result = iInnerService.getOnSaleBenefitPackage(onSaleBenefitPackageRequest);
		if (Objects.isNull(result)) {
			log.error("getOnSaleBenefitPackage failed. packageCode:{} result:{}", packageCode, JSONUtil.toJsonStr(result));
			throw new ChainException(ErrorMessage.ORDER_CREATE_FAILED);
		}
		return result;
	}
}
